#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
//#include <sys/select.h>
#include <sys/poll.h>

#include "fsm.h"

#define TTY1 "/dev/tty9"
#define TTY2 "/dev/tty10"

int main(void)
{
	int fd1, fd2;
	fsm_t *fsm12, *fsm21;
	//fd_set rset, wset;
	struct pollfd pfd[2];

	fd1 = open(TTY1, O_RDWR);
	if (-1 == fd1) {
		perror("Error opening tty");
		exit(1);
	}
	
	fd2 = open(TTY2, O_RDWR);
	if (-1 == fd2) {
		perror("Error opening tty");
		exit(1);
	}

	fsm_init(&fsm12, fd1, fd2);
	fsm_init(&fsm21, fd2, fd1);

	pfd[0].fd = fd1;
	pfd[1].fd = fd2;

	while (!(fsm12->state == STATE_T && fsm21->state == STATE_T)) {
		if (fsm12->state == STATE_E) {
			fsm_drive(fsm12);
			continue;
		}
		if (fsm21->state == STATE_E) {
			fsm_drive(fsm21);
			continue;
		}
		
		//FD_ZERO(&rset);
		//FD_ZERO(&wset);
		pfd[0].events = pfd[0].revents = 0;
		pfd[1].events = pfd[1].revents = 0;

		if (fsm12->state == STATE_R) {
			//FD_SET(fd1, &rset);
			pfd[0].events |= POLLIN;
		} else if (fsm12->state == STATE_W) {
			//FD_SET(fd2, &wset);
			pfd[1].events |= POLLOUT;
		}

		if (fsm21->state == STATE_R) {
			//FD_SET(fd2, &rset);
			pfd[1].events |= POLLIN;
		} else if (fsm21->state == STATE_W) {
			//FD_SET(fd1, &wset);
			pfd[0].events |= POLLOUT;
		}

		//if (-1 == select((fd1 > fd2 ? fd1 : fd2) + 1, &rset, &wset, NULL, NULL)) {
		while (-1 == poll(pfd, 2, -1)) {
			if (errno == EINTR) {
				continue;
			}
			perror("Error selecting");
			goto ERROR;
		}

		//if (FD_ISSET(fd1, &rset) || FD_ISSET(fd2, &wset))
		if (pfd[0].revents & POLLIN || pfd[1].revents & POLLOUT)
			fsm_drive(fsm12);

		//if (FD_ISSET(fd2, &rset) || FD_ISSET(fd1, &wset))
		if (pfd[1].revents & POLLIN || pfd[0].revents & POLLOUT)
			fsm_drive(fsm21);
	}

	fsm_destroy(&fsm12);
	fsm_destroy(&fsm21);

	return 0;

ERROR:
	fsm_destroy(&fsm12);
	fsm_destroy(&fsm21);

	return 0;
}
